grammar sql_select;

ridentifier: 
	'[\.a-z][\.\_a-z0-9]*';
rexpression: 
	'\`[^\`]+\`';
ridentifier_or_expression: 
	ridentifier | rexpression; 
column: 
	ridentifier_or_expression (| 'AS' ridentifier);
column_list: 
	'*' | column (',' column)*;
identifier_list: 
	ridentifier (',' ridentifier)*; 
single_source: 
	'(' select_stmt ')' 'AS' ridentifier | ridentifier_or_expression;
join_source: 
	single_source ( 'NATURAL JOIN' single_source 
	| ('CROSS JOIN'|' , ') single_source 
	| ('INNER JOIN'|'LEFT JOIN') single_source 
	('ON' '(' ridentifier_or_expression ')' | 'USING' '(' identifier_list ')' ) )*; 
aggregation: 
	'GROUP BY' column_list (| 'HAVING' ridentifier_or_expression); 
select_core: 
	'SELECT' (| 'DISTINCT') column_list 'FROM' join_source 
	(| 'WHERE' ridentifier_or_expression) (| aggregation); 
compound_operator: 
	'UNION' | 'INTERSECT'; 
integer_number: 
	'[0-9]+'; 
order: 
	'ORDER BY' column_list (| 'ASC' | 'DESC'); 
limit: 
	'LIMIT' integer_number (| (',' integer_number | 'OFFSET' integer_number)); 
select_stmt: 
	select_core (compound_operator select_core)* 
	(| order) (| limit); 
sql_stmt: 
	(('CREATE' (| 'TEMPORARY' | 'TEMP') ('TABLE'|'VIEW') ridentifier 'AS' '(' select_stmt ')' ) | select_stmt );
sql_stmt_sequence: 
	 ((|sql_stmt) (|';'))+;